package com.sillyhat.project.webapp.common.base;

import com.sillyhat.project.common.constants.Constants;
import com.sillyhat.project.common.dto.Message;
import com.sillyhat.project.common.editor.DateEditor;
import com.sillyhat.project.common.utils.CookieUtils;
import com.sillyhat.project.common.utils.MD5Util;
import com.sillyhat.project.org.menu.dto.MenuDTO;
import com.sillyhat.project.org.menu.service.MenuService;
import com.sillyhat.project.org.user.dto.UserDTO;
import com.sillyhat.project.org.user.dto.UserDetailDTO;
import com.sillyhat.project.org.user.service.UserService;
import com.sillyhat.project.redis.service.RedisService;
import com.sillyhat.project.sys.business.service.SystemBusinessService;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;

/**
 * Created by yuxiang on 2017/3/23.
 */
public class BaseController {

    private final Logger logger = LoggerFactory.getLogger(BaseController.class);

    protected static final String ERROR = "/admin/common/error";

    protected static final Message MESSAGE_ERROR = Message.error("admin.message.error", new Object[0]);//操作错误

    protected static final Message MESSAGE_SUCCESS = Message.success("admin.message.success", new Object[0]);//操作成功

    @Autowired
    private RedisService redisService;

    @Autowired
    private UserService userService;

    @Resource(name = "validator")
    private Validator validator;

    /**
     * 针对String和Date类型进行自解析到对应的command类（实际需要注入的bean）
     * @param webDataBinder
     */
    @InitBinder
    protected void initBinder(WebDataBinder webDataBinder) {
        webDataBinder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
        // 表示如果请求对象有Date类型的属性，将使用该属性编辑器进行类型转换
        webDataBinder.registerCustomEditor(Date.class, new DateEditor(true));
    }

    /**
     * 校验实体的约束
     *
     * @param obj 校验的实体类
     * @param cls
     * @return
     */
    protected boolean validation(Object obj, Class<?>[] groups) {
        Set<ConstraintViolation<Object>> constraintViolations = this.validator.validate(obj, groups);
        // 假如constraintViolations不为空，说明存在约束违反
        if (constraintViolations.isEmpty()) {
            return true;
        }
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        requestAttributes.setAttribute("constraintViolations", constraintViolations, 0);
        return false;
    }

    public HttpServletRequest getRequest(){
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        return request;
    }
    public void setAttribute(String key,Object value){
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        requestAttributes.setAttribute(key,value,0);
    }

    public void setSession(String key,Object value){
        HttpServletRequest request = getRequest();
        HttpSession session = request.getSession();
        session.setAttribute(key,value);
    }

    public Object getSession(String key){
        HttpServletRequest request = getRequest();
        HttpSession session = request.getSession();
        return session.getAttribute(key);
    }

    /**
     * 得到当前登录账户
     * @return
     */
    public UserDTO getCurrentUser(){
        HttpServletRequest request = getRequest();
        String jsessionid = CookieUtils.getCookie(request, Constants.DEFAULT_COOKIE_JSESSIONID);
        if(redisService.exists(Constants.CURRENT_USER+jsessionid)){
            return (UserDTO) redisService.get(Constants.CURRENT_USER+jsessionid);
        }else{
            return null;
        }
    }

    /**
     * 存储当前登录账户
     * @return
     */
    public void setCurrentUser(UserDTO user){
        HttpServletRequest request = getRequest();
        String jsessionid = CookieUtils.getCookie(request, Constants.DEFAULT_COOKIE_JSESSIONID);
        String redisKey = Constants.CURRENT_USER + jsessionid;
        redisService.set(redisKey,user,30, TimeUnit.MINUTES);//将user存入redis
    }

    /**
     * 加载主菜单
     */
    public void loadMenuHeader111(){
//        UserDTO currentUser = getCurrentUser();
//        long permissionId = Constants.PERMISSION_PUBLIC_MENU;
//        if(currentUser != null){
//            permissionId = currentUser.getId();
//        }
//        if(systemBusinessService.initSystemData()){
//            initSystem();//初始化系统
//        }
//        List<MenuDTO> permissionMenuList = menuService.queryHeaderMenuByPermission(permissionId);
//        setAttribute("permissionMenuList",permissionMenuList);
    }


    /**
     * 遍历当前节点元素下面的所有(元素的)子节点
     *
     * @param node
     */
    public void listNodes(Element node) {
        System.out.println("当前节点的名称：：" + node.getName());
        // 获取当前节点的所有属性节点
        List<Attribute> list = node.attributes();
        // 遍历属性节点
        for (Attribute attr : list) {
            System.out.println(attr.getText() + "-----" + attr.getName()
                    + "---" + attr.getValue());
        }

        if (!(node.getTextTrim().equals(""))) {
            System.out.println("文本内容：：：：" + node.getText());
        }

        // 当前节点下面子节点迭代器
        Iterator<Element> it = node.elementIterator();
        // 遍历
        while (it.hasNext()) {
            // 获取某个子节点对象
            Element e = it.next();
            // 对子节点进行遍历
            listNodes(e);
        }
    }

    private final String ELEMENT_MENU_LIST = "menuList";

    private final String ELEMENT_USER_LIST = "userList";

    public void initSystem(){
        org.springframework.core.io.Resource resource = new PathMatchingResourcePatternResolver().getResource("classpath:/template/xml/system-init.xml");
        //创建SAXReader对象
        SAXReader reader = new SAXReader();
        try {
            List<MenuDTO> menuList = null;
            List<UserDTO> userList = null;
            //读取文件 转换成Document
            Document document = reader.read(resource.getInputStream());
            //获取根节点元素对象
            Element root = document.getRootElement();
            //迭代子元素 menuList administrator
            Iterator<Element> elementIterator = root.elementIterator();
            while(elementIterator.hasNext()){
                Element element = elementIterator.next();
                if(element.getName().equals(ELEMENT_MENU_LIST)){
                    menuList = getMenuList(element);
                }else if(element.getName().equals(ELEMENT_USER_LIST)){
                    userList = getUserList(element);
                }
            }
            userService.initSystem(menuList,userList);
        } catch (DocumentException e) {
            logger.error("初始化系统时，读取xml发生异常",e);
        } catch (Exception e) {
            logger.error("初始化系统发生异常",e);
        }
    }

    private List<UserDTO> getUserList(Element element){
        List<UserDTO> userList = new ArrayList<>();
        Iterator<Element> elementIterator = element.elementIterator();
        while(elementIterator.hasNext()){
            UserDTO user = new UserDTO();
            UserDetailDTO detail = new UserDetailDTO();
            Element userElement = elementIterator.next();
            Iterator<Element> userIterator = userElement.elementIterator();
            while(userIterator.hasNext()){
                Element fieldElement = userIterator.next();
                Attribute idAttribute = fieldElement.attribute("id");
                Attribute valueAttribute = fieldElement.attribute("value");
                user.setIsAdministrators(1);
                if(idAttribute.getValue().equals("login")){
                    user.setLogin(valueAttribute.getValue());
                }else if(idAttribute.getValue().equals("password")){
                    user.setPassword(valueAttribute.getValue());
                }else if(idAttribute.getValue().equals("username")){
                    detail.setUserName(valueAttribute.getValue());
                }else if(idAttribute.getValue().equals("age")){
                    detail.setUserAge(getIntegerType(valueAttribute.getValue()));
                }else if(idAttribute.getValue().equals("phone")){
                    detail.setUserPhone(valueAttribute.getValue());
                }else if(idAttribute.getValue().equals("gender")){
                    detail.setUserGender(getIntegerType(valueAttribute.getValue()));
                }else if(idAttribute.getValue().equals("email")){
                    detail.setUserEmail(valueAttribute.getValue());
                }else if(idAttribute.getValue().equals("identitycard")){
                    detail.setIdentityCard(valueAttribute.getValue());
                }else if(idAttribute.getValue().equals("icon")){
                    detail.setUserIcon(valueAttribute.getValue());
                }
            }
            user.setUserDetail(detail);
            userList.add(user);
        }
        return userList;
    }

    private MenuDTO getMenu(Element menuElement){
        MenuDTO menuDTO = new MenuDTO();
        //获取当前节点的所有属性节点
        List<Attribute> menuAttribute = menuElement.attributes();
        for (Attribute attribute : menuAttribute) {
            if(attribute.getName().equals("code")){
                menuDTO.setMenuCode(attribute.getValue());
            }else if(attribute.getName().equals("name")){
                menuDTO.setMenuName(attribute.getValue());
            }else if(attribute.getName().equals("link")){
                menuDTO.setMenuLink(attribute.getValue());
            }else if(attribute.getName().equals("type")){
                menuDTO.setMenuType(getIntegerType(attribute.getValue()));
            }else if(attribute.getName().equals("icon")){
                menuDTO.setMenuIcon(attribute.getValue());
            }else if(attribute.getName().equals("sort")){
                menuDTO.setMenuSort(getIntegerType(attribute.getValue()));
            }else if(attribute.getName().equals("isDisabled")){
                menuDTO.setIsDisabled(getIntegerType(attribute.getValue()));
            }else if(attribute.getName().equals("isDelete")){
                menuDTO.setIsDelete(getIntegerType(attribute.getValue()));
            }else if(attribute.getName().equals("isCommon")){
                menuDTO.setIsCommon(getIntegerType(attribute.getValue()));
            }
        }
        //当前节点下面子节点迭代器
        Iterator<Element> it = menuElement.elementIterator();
        List<MenuDTO> chileMenuList = new ArrayList<>();
        while(it.hasNext()) {
            //获取某个子节点对象
            Element childMenu = it.next();
            //对子节点进行遍历并导入menu list
            chileMenuList.add(getMenu(childMenu));
        }
        if(chileMenuList.size()>0){
            menuDTO.setChildMenus(chileMenuList);
        }
        return menuDTO;
    }
    private List<MenuDTO> getMenuList(Element menuListElement){
        List<MenuDTO> list = new ArrayList<>();
        Iterator<Element> elementIterator = menuListElement.elementIterator();
        while(elementIterator.hasNext()){
            Element menuElement = elementIterator.next();
            list.add(getMenu(menuElement));
        }
        return list;
    }

    private int getIntegerType(String value){
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException e) {
            return 0;
        }
    }


    private void initTestUser(){
        for (int i = 1; i < 100; i++) {
            if(i != 1){
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            UserDTO dto = new UserDTO();
            int index = i+1;
            dto.setLogin("tempdk" + index);
            dto.setPassword(MD5Util.toMD5Upper("1"));
            dto.setIsAdministrators(0);
            dto.setIsDelete(0);
            dto.setCreatedUser(1l);
            dto.setUpdatedUser(1l);
            UserDetailDTO userDetail = new UserDetailDTO();
            userDetail.setUserName("tempdkUserName" + index);//用户名
            int max=40;
            int min=20;
            Random random = new Random();
            int age = random.nextInt(max)%(max-min+1) + min;
            userDetail.setUserAge(age);//年龄
            userDetail.setUserGender(i%3);//性别；0：未知；1：男；2：女
            userDetail.setIdentityCard("12332454984");//身份证号
            userDetail.setUserBirthday(new Date());//出生日期
            userDetail.setUserPhone("1234567" + index);//手机号
            userDetail.setUserEmail("1234567" + index + "@qq.com");//邮箱
            userDetail.setUserIcon(null);//用户头像
            userDetail.setCompanyId(null);//公司ID
            userDetail.setDepartmentId(null);//部门ID
            userDetail.setIsJob(1);//是否在职；0：离职；1：在职
            dto.setUserDetail(userDetail);
            userService.addUser(dto);
        }
    }
}
